﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using QxFramework.Core;
using GameControl;
using System;
public class EnemyItem : CombinableItem
{
    public EnemyItemField NewSetting;

    public float Power = 0;

    [Header("两次攻击的间隔")]
    public float AttackGap=2;

    float MaxSpeed = 3;
    /// <summary>
    /// 做出新判断的时间间隔
    /// </summary>
    float DecisionTimeGap = 0.1f;

  //  float FollowTargetTime = 3f;

    public override ItemField ItemFieldSetting { get => NewSetting; set => NewSetting = value as EnemyItemField; }
    /// <summary>
    /// 敌人视野
    /// </summary>
    public BoxCollider2D ViewRange;

    /// <summary>
    /// 用于检测是否能朝碰撞体方向移动
    /// </summary>
    public List<BoxCollider2D> MoveDetects;
    /// <summary>
    /// 触发攻击范围
    /// </summary>
    public BoxCollider2D AttackRange;

    protected string handholdExtentName;
    public override void OnAwake()
    {
        base.OnAwake();
        _anim = this.transform.Find("Sprite").GetComponentInChildren<Animator>();
        _handHold = this.transform.Find("Sprite").Find("Animation").Find("HandHoldAnimation").gameObject;
        MoveDetects = new List<BoxCollider2D>(this.transform.Find("Collider").Find("MoveDetects").GetComponentsInChildren<BoxCollider2D>());
        ViewRange = this.transform.Find("Sprite").Find("ViewRange").GetComponent<BoxCollider2D>();
        AttackRange = this.transform.Find("Sprite").Find("AttackRange").GetComponent<BoxCollider2D>();
    }
    public override void OnStart()
    {
        Debug.Assert(handholdExtentName == default);

            MessageManager.Instance.Get<GameMap.ItemMapEvent>().DispatchMessage(GameMap.ItemMapEvent.CreateInMap, this, new GameMap.ItemCreateArgs("MagicAttackExtent", ItemFieldSetting.Position, (ItemField x) =>
            {
                //  ((((e as UniversalEventArgs).Info) as Item).ItemFieldSetting as AttackExtentItemField).Power = 0;
                (x as AttackExtentItemField).Power = Power;
                handholdExtentName = x.ItemName;
                x.Position = this.transform.position;
                GameManager.Get<IItemHealthManager>().IgnorePairs.UniqueAdd(new Tuple<string, string>(handholdExtentName, ItemFieldSetting.ItemName));

                //       Debug.Log(handholdItemName + " " + ItemFieldSetting.ItemName);

            }));
    }
    public override void OnPreferenceDestory()
    {
        base.OnPreferenceDestory();
        if (handholdExtentName != default)
        {
            //当自身销毁,连带销毁子物体
            MessageManager.Instance.Get<GameMap.ItemMapEvent>().DispatchMessage(GameMap.ItemMapEvent.DeleteInMap, this, new GameMap.ItemMapArgs { ItemName =handholdExtentName}, null);
        }
       handholdExtentName= default;
    }
    public override void OnRealDestory()
    {
        base.OnRealDestory();
        if (string.IsNullOrEmpty(GetField<EnemyItemField>().DropItemName)==false)
        {
      //      string dropName = GetField<EnemyItemField>().DropItemName;
            MessageManager.Instance.Get<GameMap.ItemMapEvent>().DispatchMessage(GameMap.ItemMapEvent.CreateInMap, this, new GameMap.ItemCreateArgs("CollectableItem",ItemFieldSetting.Position,(ItemField item)=>
            {
                //强制转型后获取id
                (item as CollectableItemField).CanCollectItemName = (this.ItemFieldSetting as EnemyItemField).DropItemName;
            }));
        }
    }

    Animator _anim;
    protected GameObject _handHold;
    public override float SetRigidInfo(Rigidbody2D rigid)
    {
        var mass=base.SetRigidInfo(rigid);
        rigid.freezeRotation = true;
          return mass;
    }
    int _lastIndex = 0;
    string lastTargetName;
    public virtual bool Follow()
    {
        var list = ViewRange.GetInColliderParent<CombinableItem>(LayerMask.NameToLayer("Player"));
        list.RemoveAll(s => s.ItemFieldSetting.ItemName == this.ItemFieldSetting.ItemName);
        if (list.Count == 0)
        {
            return false;
        }
        list.Sort((CombinableItem x,CombinableItem y) => {
            var disx = Vector2.Distance(x.ItemFieldSetting.Position, this.ItemFieldSetting.Position);
            var disy = Vector2.Distance(y.ItemFieldSetting.Position, this.ItemFieldSetting.Position);
            if (x.ItemFieldSetting.ItemName == lastTargetName) return -1;
            if (y.ItemFieldSetting.ItemName == lastTargetName) return 1;
            if (disx - disy < 0) return -1;
            else if (disx - disy > 0) return 1;
            else return 0;
        });
        MoveTowards(list[0].ItemFieldSetting.Position);
        lastTargetName = list[0].ItemFieldSetting.ItemName;
        return true;
    }
    public virtual bool Wander()
    {
        int index = UnityEngine.Random.Range(0, MoveDetects.Count);
        if (_lastIndex != index)
        {
            if (UnityEngine.Random.Range(0, 10) < 1)//限制转向概率
            {
                _lastIndex = index;
            }
            else
            {
                index = _lastIndex;
            }
        }
        //Debug.Log("index:"+index);
        if (CheckCanMove(MoveDetects[index]))
        {
            MoveTowards(MoveDetects[index].transform.position);
            return true;
        }
        else
        {
            MoveTowards(CenterInWorld);
            return false;
        }
    }
    bool CheckCanMove(BoxCollider2D detect)
    {
        var list = detect.GetInColliderParent<PosFixedItem>();
        if (list.Count == 0) return false;
        foreach(var x in list)
        {
            if (x.transform.position.y > detect.transform.position.y)
            {
                return false;
            }
        }
        return true;
    }
    float lastDecisionTime = float.NegativeInfinity;
    void LowerDecision()
    {
        if (Follow() == false)
        {
    //        Debug.Log("Wander");
            Wander();

        }
    }
    public virtual void Attack()
    {
        _anim.SetTrigger("Attack");
    }
    float lastAttackTime = float.NegativeInfinity;
    void UpperDecision()
    {
        var list = AttackRange.GetInColliderParent<CombinableItem>(LayerMask.NameToLayer("Player"));
        list.RemoveAll(s => s.ItemFieldSetting.ItemName == this.ItemFieldSetting.ItemName);
        if (list.Count > 0)
        {
            Debug.Log(list[0].gameObject);
            GetField<EnemyItemField>().EnemyUpperMotion = EnemyUpperMotionState.Attack;
            if (Time.time-lastAttackTime   > AttackGap)
            {
                Attack();
                lastAttackTime = Time.time;
            }
        }
        else
        {
            GetField<EnemyItemField>().EnemyUpperMotion = EnemyUpperMotionState.Normal;
        }
    }
    public override  void FixedUpdateInLogic()
    {
        base.FixedUpdateInLogic();
        RefreshHandHoldCollider();
        if (physic.Rigid == null)
        {
            return;
        }
        if (Time.time - lastDecisionTime > DecisionTimeGap)
        {
            lastDecisionTime = Time.time;
            UpperDecision();
            LowerDecision();

        }
        _anim.SetFloat("Upper",(float)GetField<EnemyItemField>().EnemyUpperMotion);
        _anim.SetFloat("Lower",(float)GetField<EnemyItemField>().EnemyLowerMotion);

       // _handHoldSprite= this.transform.Find("Sprite").Find("Animation").Find("HandHoldAnimation").GetComponentInChildren<SpriteRenderer>();
        //tp.
    }
    public override void FixedUpdateInPresentation()
    {
        base.FixedUpdateInPresentation();
        RefreshFlip();
    }
    protected Vector2 CenterInWorld
    {
        get
        {
            return this.transform.position;
        }
    }
    protected bool IsMoving
    {
        get
        {
            return Mathf.Abs(physic.Rigid.velocity.x) > 0.01;
        }
    }
    /// <summary>
    /// 敌人向某个方向移动
    /// </summary>
    /// <param name="target">目标坐标</param>
    public virtual void MoveTowards(Vector3 target)
    {
        var distanceX =(Vector2)target-CenterInWorld;
        //Debug.Log(distanceX.x);
        if (Mathf.Abs(distanceX.x) < 0.01)
        {
            physic.Rigid.velocity = new Vector2(0, physic.Rigid.velocity.y);
            GetField<EnemyItemField>().EnemyLowerMotion = EnemyLowerMotionState.Stand;
        }
        else if (distanceX.x < 0)
        {
            physic.Rigid.velocity = new Vector2(-MaxSpeed, physic.Rigid.velocity.y);
            GetField<EnemyItemField>().EnemyLowerMotion = EnemyLowerMotionState.Walk;
        }
        else
        {
            physic.Rigid.velocity = new Vector2(MaxSpeed, physic.Rigid.velocity.y);
            GetField<EnemyItemField>().EnemyLowerMotion = EnemyLowerMotionState.Walk;
        }

    }/// <summary>
    /// 翻转,保持前后重心一致
    /// </summary>
    public virtual void RefreshFlip()
    {
        //Vector3 masspos =physic.transform.TransformPoint(physic.Rigid.centerOfMass);
        if (IsMoving)
        {
            this.sprite.transform.localScale = new Vector3(Mathf.Abs(this.sprite.transform.localScale.x)*(physic.Rigid.velocity.x<0?1:-1), this.sprite.transform.localScale.y, this.sprite.transform.localScale.z);
        }
      //  this.transform.position =masspos- physic.transform.TransformPoint(physic.Rigid.centerOfMass)  + this.transform.position;
    }
    public virtual void  RefreshHandHoldCollider() 
    {

    //    return;
        var item= ClockManager.Get<IItemSyncManager>().GetGameObjectByName(handholdExtentName);
        if (item == null)
        {
            return;
        }
        UnsafeTool.RefreshPolygonColliderBySprite(item, _handHold.GetComponent<SpriteRenderer>().sprite);
        item.transform.position = _handHold.transform.position;
        item.transform.localScale = this.sprite.transform.localScale;

    }
    
    private void OnDrawGizmos()
    {
        Gizmos.DrawCube(CenterInWorld, Vector3.one * 0.2f);
        foreach(var x in MoveDetects)
        {
            Gizmos.DrawCube(x.transform.position, Vector3.one * 0.2f);
        }
    }
}
public enum EnemyUpperMotionState
{
    Normal=0,Attack=1
}
public enum EnemyLowerMotionState
{
    Stand=0,Walk=1
}
[System.Serializable]
public class EnemyItemField : CombinableItemField
{
    [HideInInspector]
    public EnemyUpperMotionState EnemyUpperMotion;
    [HideInInspector]
    public EnemyLowerMotionState EnemyLowerMotion;
    /// <summary>
    /// 敌兵死亡后掉落的物品,若未设置则不掉落
    /// </summary>
    [Header("默认掉落物品名称")]
    public string DropItemName = default;
}